/*
	*	SunPos 1.0 EA3HMJ 03-2.014
	*	Portable sun & moon position
	* 	For Arduino, NNEA & Motorola binary protocol
	*
	* 	Based on Arduino Rotator Controller
	* 	Anthony Good
	* 	K3NG
	* 	anthony.good@gmail.com
	*
	* 	Moon2 and sunpos libraries courtesy of Pete Hardie, VE5VA
	*
 */

#include <avr/pgmspace.h>
#include <math.h>
#include <LiquidCrystal.h>  // required for classic 4 bit interface LCD display (FEATURE_4_BIT_LCD_DISPLAY)
#include "sunpos.h"
#include "moon2.h"
#include "TinyGPS.h"

//LCD pins
#define RS 2
#define RW 3
#define Enable 4
#define D4 5
#define D5 6
#define D6 7
#define D7 8

#define moon_tracking_button 	9	// to gnd moon, open sun
#define locator_button 			10	// to gnd locator 10 digits
#define gps_button 				11	// to gnd NMEA 4800, Binary 9600

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(RS, RW,Enable, D4, D5, D6, D7);

#define INTERNAL_CLOCK_CORRECTION 0.00145

#define LCD_COLUMNS 16
#define LCD_ROWS 2
#define LCD_BIG_CLOCK_ROW 1
#define LCD_SUN_TRACKING_ROW 2                                    // LCD display row for OPTION_DISPLAY_SUN_TRACKING_CONTINUOUSLY
#define LCD_SUN_TRACKING_UPDATE_INTERVAL 5000
#define LCD_MOON_TRACKING_UPDATE_INTERVAL 5000 
#define SPLASH_SCREEN_TIME 3000
#define LCD_LOCATOR_UPDATE_INTERVAL 2000

#define CONTROL_PORT_MAPPED_TO &Serial  // change this line to map the control port to a different serial port (Serial1, Serial2, etc.)
#define GPS_PORT_MAPPED_TO &Serial  // change this line to map the GPS port to a different serial port
#define CONTROL_PORT0 1
#define CONTROL_PORT_BAUD_RATE 9600
#define GPS_PORT_BAUD_RATE 4800
#define GPS_B_PORT_BAUD_RATE 9600
#define COMMAND_BUFFER_SIZE 80

#define SYNC_TIME_WITH_GPS 1
#define SYNC_COORDINATES_WITH_GPS 1
#define GPS_SYNC_PERIOD_SECONDS 10  // how long to consider internal clock syncronized after a GPS reading
#define GPS_VALID_FIX_AGE_MS 10000  // consider a GPS reading valid if the fix age is less than this
#define GPS_UPDATE_LATENCY_COMPENSATION_MS 200
#define FREE_RUNNING 0 
#define GPS_SYNC 1

/*----------------------- variables -------------------------------------*/

double latitude = 41.5695487927695;
double longitude = 2.01394253306921;
int sec=0;
float sun_azimuth = 0;
float sun_elevation = 0;
cTime c_time;
cLocation c_loc;
cSunCoordinates c_sposn;
byte sun_visible = 0;
//byte sun_tracking_active = 0;
unsigned long clock_years = 0;
unsigned long clock_months = 0;
unsigned long clock_days =0;
unsigned long clock_hours = 0;
unsigned long clock_minutes = 0;
unsigned long clock_seconds = 0;
int clock_year_set = 0;
byte clock_month_set = 0;
byte clock_day_set = 0;
byte clock_sec_set = 0;
unsigned long clock_hour_set = 0;
unsigned long clock_min_set = 0;
unsigned long millis_at_last_calibration = 0;
byte debug_mode = 0;
unsigned long last_lcd_update = 0;
byte incoming_serial_byte = 0;
byte control_port_buffer[COMMAND_BUFFER_SIZE];
int control_port_buffer_index = 0;
unsigned long last_serial_receive_time = 0;
HardwareSerial * control_port;
HardwareSerial * gps_port;
byte gps_data_available = 0;
TinyGPS gps;
byte last_byte=0;
byte gps_start=0;
byte clock_status = FREE_RUNNING;
byte updateLocator=1;
//byte moon_tracking_active = 0;
byte moon_visible = 0;
double moon_azimuth = 0;
double moon_elevation = 0;
byte btn_moon_sun=0;	// 0 sun 1 moon
byte btn_locator=0;		// 0 6 digitos, 1 10 digitos
byte btn_gps_type=1;	// 0 NMEA, 1 binary

/* ------------------ let's start doing some stuff now that we got the formalities out of the way --------------------*/
void setup() {
	delay(100);
	
    pinMode(moon_tracking_button, INPUT);
    digitalWrite(moon_tracking_button, HIGH);
    pinMode(locator_button, INPUT);
    digitalWrite(locator_button, HIGH);
    pinMode(gps_button, INPUT);
    digitalWrite(gps_button, HIGH);
	initialize_display();
	if ((digitalRead(gps_button) == LOW)) {
		btn_gps_type=0;
	}
	initialize_serial();
	
} /* setup */

/*-------------------------- here's where the magic happens --------------------------------*/
void loop() {

	check_buttons();
	check_serial();
	service_gps();
	update_display();

} /* loop */
/* -------------------------------------- subroutines -----------------------------------------------
 *
 * Where the real work happens...
 *
 */

// --------------------------------------------------------------
void update_moon_position(){
  double RA, Dec, topRA, topDec, LST, HA, dist;
  update_time();
  moon2(clock_years, clock_months, clock_days, (clock_hours + (clock_minutes / 60.0) + (clock_seconds / 3600.0)), longitude, latitude, &RA, &Dec, &topRA, &topDec, &LST, &HA, &moon_azimuth, &moon_elevation, &dist);
}
void update_sun_position(){

  update_time();
  c_time.iYear = clock_years;
  c_time.iMonth = clock_months;
  c_time.iDay = clock_days;

  c_time.dHours = clock_hours;
  c_time.dMinutes = clock_minutes;
  c_time.dSeconds = clock_seconds;

  c_loc.dLongitude = longitude;
  c_loc.dLatitude  = latitude;

  c_sposn.dZenithAngle = 0;
  c_sposn.dAzimuth = 0;

  sunpos(c_time, c_loc, &c_sposn);

  // Convert Zenith angle to elevation
  sun_elevation = 90. - c_sposn.dZenithAngle;
  sun_azimuth = c_sposn.dAzimuth;

} /* update_sun_position */

void update_time(){
  unsigned long runtime = millis() - millis_at_last_calibration;

  unsigned long time = (3600L * clock_hour_set) + (60L * clock_min_set) + clock_sec_set + ((runtime + (runtime * INTERNAL_CLOCK_CORRECTION)) / 1000.0);

  clock_years = clock_year_set;
  clock_months = clock_month_set;
  clock_days = time / 86400L;
  time -= clock_days * 86400L;
  clock_days += clock_day_set;
  clock_hours = time / 3600L;

  switch (clock_months) {

    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
      if (clock_days > 31) {
        clock_days = 1; clock_months++;
      }
      break;

    case 2:
      if ((float(clock_years) / 4.0) == 0.0) {  // do we have a leap year?
        if (clock_days > 29) {
          clock_days = 1; clock_months++;
        }
      } else {
        if (clock_days > 28) {
          clock_days = 1; clock_months++;
        }
      }
      break;

    case 4:
    case 6:
    case 9:
    case 11:
      if (clock_days > 30) {
        clock_days = 1; clock_months++;
      }
      break;
  } /* switch */

  if (clock_months > 12) {
    clock_months = 1; clock_years++;
  }

  time -= clock_hours * 3600L;
  clock_minutes  = time / 60L;
  time -= clock_minutes * 60L;
  clock_seconds = time;
} /* update_time */

void update_display(){
 static byte lcd_state_row_0 = 0;
  static byte lcd_state_row_1 = 0;
  char trackingstring[LCD_COLUMNS+2];
  char temptrackingstring[LCD_COLUMNS+2];
 char temp_string[10];
  char clock_big_temp_string[10];
  char locator_tmp[11];
  
   if ((lcd_state_row_0 == 0) ){
    if (millis() < SPLASH_SCREEN_TIME){
      return;
    } else {
      lcd.clear();
      lcd_state_row_0 = 1;
	  updateLocator=1;
    }
  }
 
   static unsigned long last_locator_tracking_check_time = 0;
   if (((millis()-last_locator_tracking_check_time) > LCD_LOCATOR_UPDATE_INTERVAL) ) {  
		if (btn_locator==1){
			latlng2loc(latitude,longitude,locator_tmp);
			lcd.setCursor(0,LCD_BIG_CLOCK_ROW-1);
			// scroll locator to left
			locator_tmp[lcd_state_row_1+7]=0;
			lcd.print(&locator_tmp[lcd_state_row_1++]);
			if (lcd_state_row_1==4)
				lcd_state_row_1=0;
		}else{
			if (updateLocator){
				latlng2loc(latitude,longitude,locator_tmp);
				lcd.setCursor(0,LCD_BIG_CLOCK_ROW-1);
				locator_tmp[6]=0;
				lcd.print(locator_tmp);
				updateLocator =0;
			}
		}
		last_locator_tracking_check_time = millis();			
	}
	
	
  static byte last_clock_big_seconds = 0;
  static byte last_clock_big_minutes = 0;

  update_time();
  if ((last_clock_big_seconds != clock_seconds) ){//&& (lcd_state_row_0 != 0) && (lcd_state_row_1 != 0)){

  
    sprintf(clock_big_temp_string, "%s", clock_string()); 
    if (last_clock_big_minutes == clock_minutes){  // if the minutes didn't change, don't send the whole string to the LCD
		if ((int(float(last_clock_big_seconds)/10.0)) != (int(float(clock_seconds)/10.0))){   
			lcd.setCursor(14,LCD_BIG_CLOCK_ROW-1);
			lcd.print(clock_big_temp_string[6]);
		} else {
			lcd.setCursor(15,LCD_BIG_CLOCK_ROW-1);
		}
		lcd.print(clock_big_temp_string[7]);
			last_clock_big_seconds = clock_seconds;
    } else {  // print the whole clock
		lcd.setCursor(8,LCD_BIG_CLOCK_ROW-1);
		lcd.print(clock_big_temp_string);
		last_clock_big_seconds = clock_seconds;
		last_clock_big_minutes = clock_minutes;
    }
  }
  // end clock display --- big clock ---------------------------------------------------------
  
  static unsigned long last_sun_tracking_check_time = 0;
  static byte last_strlen_sun = 0;

  if (((millis()-last_sun_tracking_check_time) > LCD_SUN_TRACKING_UPDATE_INTERVAL) && (btn_moon_sun==0)) {  
	if (debug_mode & CONTROL_PORT0)
		control_port->println("track sun");
    update_sun_position();
    strcpy(trackingstring,"");


    strcat(trackingstring,"sun ");
    dtostrf(sun_azimuth,0,1,temp_string);
    strcat(trackingstring,temp_string);
    if ((LCD_COLUMNS>16) && ((sun_azimuth < 100) || (abs(sun_elevation)<100))) {strcat(trackingstring,"\xDF");}
    strcat(trackingstring," ");
    dtostrf(sun_elevation,0,1,temp_string);
    strcat(trackingstring,temp_string);
    if ((LCD_COLUMNS>16) && ((sun_azimuth < 100) || (abs(sun_elevation)<100))) {strcat(trackingstring,"\xDF");}
     lcd.setCursor(0,LCD_SUN_TRACKING_ROW-1);
    int x = LCD_COLUMNS - strlen(trackingstring);
    byte y = 0;
    while (x > 0){
      if ((y%2) != 0){
        strcpy(temptrackingstring," ");
        strcat(temptrackingstring,trackingstring);
        strcpy(trackingstring,temptrackingstring);
      } else {
        strcat(trackingstring," ");
      }
      y++;
      x--;
    }

	if (debug_mode & CONTROL_PORT0)
		control_port->println(trackingstring);

    lcd.print(trackingstring);
    last_sun_tracking_check_time = millis();
  }
  
 static unsigned long last_moon_tracking_check_time = 0;
  static byte last_strlen_moon = 0;

  if (((millis()-last_moon_tracking_check_time) > LCD_MOON_TRACKING_UPDATE_INTERVAL)&& (btn_moon_sun==1)) {  
    update_moon_position();
    strcpy(trackingstring,"");
 /*   if (moon_tracking_active){
      if (moon_visible){
        strcat(trackingstring,"*");
      } else {
        strcat(trackingstring,"-");
      }
    }*/
    strcat(trackingstring,"moon ");
    dtostrf(moon_azimuth,0,1,temp_string);
    strcat(trackingstring,temp_string);
    if ((LCD_COLUMNS>16) && ((moon_azimuth < 100) || (abs(moon_elevation)<100))) {strcat(trackingstring,"\xDF");}
    strcat(trackingstring," ");
    dtostrf(moon_elevation,0,1,temp_string);
    strcat(trackingstring,temp_string);
    if ((LCD_COLUMNS>16) && ((moon_azimuth < 100) || (abs(moon_elevation)<100))) {strcat(trackingstring,"\xDF");}
 /*   if (moon_tracking_active){
      if (moon_visible){
        strcat(trackingstring,"*");
      } else {
        strcat(trackingstring,"-");
      }
    }*/
    lcd.setCursor(0,LCD_SUN_TRACKING_ROW-1);
    int x = LCD_COLUMNS - strlen(trackingstring);
    byte y = 0;
    while (x > 0){
      if ((y%2) != 0){
        strcpy(temptrackingstring," ");
        strcat(temptrackingstring,trackingstring);
        strcpy(trackingstring,temptrackingstring);
      } else {
        strcat(trackingstring," ");
      }
      y++;
      x--;
    }



    lcd.print(trackingstring);
    last_moon_tracking_check_time = millis();
  }
   
  
}

char * clock_string(){

  char return_string[10];
  char temp_string[8];
  return_string[0]=0;
  if (clock_hours < 10) {
    strcat(return_string, "0");
  }
  dtostrf(clock_hours, 0, 0, temp_string);
  strcat(return_string, temp_string);
  strcat(return_string, ":");
  if (clock_minutes < 10) {
    strcat(return_string, "0");
  }
  dtostrf(clock_minutes, 0, 0, temp_string);
  strcat(return_string, temp_string);
  strcat(return_string, ":");
  if (clock_seconds < 10) {
    strcat(return_string, "0");
  }
  dtostrf(clock_seconds, 0, 0, temp_string);
  strcat(return_string, temp_string);
  
  return return_string;

} /* clock_string */

void initialize_display(){
	byte start_row = 0;

	lcd.begin(LCD_COLUMNS, LCD_ROWS);
	lcd.setCursor(((LCD_COLUMNS - 6) / 2), start_row);
	lcd.print("EA3HMJ");                           
	lcd.setCursor(((LCD_COLUMNS - 16) / 2), start_row + 1);
	lcd.print("Moon & Sun Posi.");
		//   1234567890123456
	last_lcd_update = millis();

} /* initialize_display */

void initialize_serial(){

  gps_port = GPS_PORT_MAPPED_TO;
  if (btn_gps_type==1){
	gps_port->begin(GPS_B_PORT_BAUD_RATE);
	// Send initial data to bufer data each s
	/*
	movlw   "@"
	movlw   "@"
	movlw   "E"
	movlw   "a"
	movlw   0x01        ;Send Position/Status data message every second
	movlw   0x25        ;Checksum  "E" XOR "a" XOR 0x01
	movlw   0x0D        ;Terminated with cr/lf
	movlw   0x0A
	*/
	gps_port->print("@@Ea\0x1\0x25\r\n");
  }else
	gps_port->begin(GPS_PORT_BAUD_RATE);
  
  control_port =gps_port;

} /* initialize_serial */

void service_gps(){

  long gps_lat, gps_lon;
  unsigned long fix_age;
  double tmp;
  int gps_year;
  byte gps_month, gps_day, gps_hours, gps_minutes, gps_seconds, gps_hundredths;
  byte gps_sync_pin_active = 0;
  #ifdef DEBUG_GPS
  char tempstring[10];
  #endif //#ifdef DEBUG_GPS

  static unsigned long last_sync = 0;

  if (gps_data_available) {
	if (btn_gps_type==1){
// 76 bytes + cr+lf
// @@Eamdyyhmsffffaaaaaooooohhhhmmmmvvhhddtntimsdimsdimsdimsdimsdimsdimsdimsds<C><CR><LF>
// 0        0         0         0         0 2       0         0         0       8
//          1         2         3         4         5         6         7       
//n = number of visible satellites (0 to 12)
//t = number of satellites tracked (0 to 8)
//40  40  45 61 09  1D  07  DD  11  2A  0C  00  00  00  00  08  EB  7C  1E  00  6E  A1  15  00  00  96  D1  00  00  00  00  00  02  04  BB  00  14  00  0B  08  01  08 32  A2  20  08  2D  A2  14  08  2E A2  0B  08  2F  A2  11  08  2E  A2  17  08  2D  A2  13  07  1F  00  1F  08  29  A2  20  F9   0D 0A
		fix_age=1;
		gps_month=control_port_buffer[2];
		gps_day=control_port_buffer[3];
		gps_year=control_port_buffer[4]*256+control_port_buffer[5];
		
		gps_hours=control_port_buffer[6];
		gps_minutes=control_port_buffer[7];
		gps_seconds=control_port_buffer[8];
		gps_hundredths=control_port_buffer[9]*16777216L+control_port_buffer[10]*65536L+control_port_buffer[11]*256L+control_port_buffer[12];
		
		gps_lat=control_port_buffer[13]*16777216L+control_port_buffer[14]*65536L+control_port_buffer[15]*256L+control_port_buffer[16];
		tmp=(double(gps_lat)/double(324.0))*double(90.0);
		gps_lat=long(tmp);
		gps_lon=control_port_buffer[17]*16777216L+control_port_buffer[18]*65536L+control_port_buffer[19]*256L+control_port_buffer[20];
		tmp=(double(gps_lon)/double(648.0))*double(180.0);
		gps_lon=long(tmp);
						
	}else{
		// retrieves +/- lat/long in 100000ths of a degree
		gps.get_position(&gps_lat, &gps_lon, &fix_age);
		gps.crack_datetime(&gps_year, &gps_month, &gps_day, &gps_hours, &gps_minutes, &gps_seconds, &gps_hundredths, &fix_age);
	}
    #ifdef DEBUG_GPS
//    #ifdef DEBUG_GPS_SERIAL
    control_port->println("");
//    #endif //DEBUG_GPS_SERIAL    
    control_port->print("service_gps: fix_age:");
    control_port->print(fix_age);
    control_port->print(" lat:");
    control_port->print(gps_lat);
    control_port->print(" long:");
    control_port->print(gps_lon);
    control_port->print(" ");
    control_port->print(gps_year);
    control_port->print("-");
    control_port->print(gps_month);
    control_port->print("-");
    control_port->print(gps_day);
    control_port->print(" ");
    control_port->print(gps_hours);
    control_port->print(":");
    control_port->print(gps_minutes);
	control_port->println("");
    #endif // DEBUG_GPS

    if (fix_age < GPS_VALID_FIX_AGE_MS) {

      if (SYNC_TIME_WITH_GPS) {
        clock_year_set = gps_year;
        clock_month_set = gps_month;
        clock_day_set = gps_day;
        clock_hour_set = gps_hours;
        clock_min_set = gps_minutes;
        clock_sec_set = gps_seconds;
        millis_at_last_calibration = millis() - GPS_UPDATE_LATENCY_COMPENSATION_MS;
        update_time();
        #ifdef DEBUG_GPS
        #ifdef DEBUG_GPS_SERIAL
        debug_println("");
        #endif //DEBUG_GPS_SERIAL        
        debug_print("service_gps: clock sync:");
        sprintf(tempstring,"%s",clock_string());
        debug_print(tempstring);
        debug_println("");
        #endif // DEBUG_GPS
		
      }

      #if defined(OPTION_SYNC_RTC_TO_GPS) && defined(FEATURE_RTC_DS1307)
      static unsigned long last_rtc_gps_sync_time;
      if ((millis() - last_rtc_gps_sync_time) >= (SYNC_RTC_TO_GPS_SECONDS * 1000)) {
        rtc.adjust(DateTime(gps_year, gps_month, gps_day, gps_hours, gps_minutes, gps_seconds));
        #ifdef DEBUG_RTC
        debug_println("service_gps: synced RTC");
        #endif // DEBUG_RTC
        last_rtc_gps_sync_time = millis();
      }
      #endif // defined(OPTION_SYNC_RTC_TO_GPS) && defined(FEATURE_RTC_DS1307)

      #if defined(OPTION_SYNC_RTC_TO_GPS) && defined(FEATURE_RTC_PCF8583)
      static unsigned long last_rtc_gps_sync_time;
      if ((millis() - last_rtc_gps_sync_time) >= (SYNC_RTC_TO_GPS_SECONDS * 1000)) {
        rtc.year = gps_year;
        rtc.month = gps_month;
        rtc.day = gps_day;
        rtc.hour  = gps_hours;
        rtc.minute = gps_minutes;
        rtc.second = gps_seconds;
        rtc.set_time();
        #ifdef DEBUG_RTC
        debug_println("service_gps: synced RTC");
        #endif // DEBUG_RTC
        last_rtc_gps_sync_time = millis();
      }
      #endif // defined(OPTION_SYNC_RTC_TO_GPS) && defined(FEATURE_RTC_PCF8583)


      if (SYNC_COORDINATES_WITH_GPS) {
		latitude = float(gps_lat) / 1000000.0;
		longitude = float(gps_lon) / 1000000.0;
		updateLocator =1;

        #ifdef DEBUG_GPS
        debug_print("service_gps: coord sync:");
        debug_print_float(latitude,2);
        debug_print(" ");
        debug_print_float(longitude,2);
        debug_println("");
        #endif // DEBUG_GPS
      }

      last_sync = millis();
    }

    gps_data_available = 0;
  }

  if ((millis() > (GPS_SYNC_PERIOD_SECONDS * 1000)) && ((millis() - last_sync) < (GPS_SYNC_PERIOD_SECONDS * 1000)) && (SYNC_TIME_WITH_GPS)) {
    clock_status = GPS_SYNC;
  } else {
    if (clock_status == GPS_SYNC) {
      clock_status = FREE_RUNNING;
    }
  }


} /* service_gps */

// --------------------------------------------------------------
void check_serial(){

  static unsigned long serial_led_time = 0;
  float tempfloat = 0;
  char return_string[100]; 

 
  #ifdef FEATURE_CLOCK
  int temp_year = 0;
  byte temp_month = 0;
  byte temp_day = 0;
  byte temp_minute = 0;
  byte temp_hour = 0;
  #endif // FEATURE_CLOCK

  char grid[8];
  byte hit_error = 0;

  if (gps_port->available()) {
    byte gps_port_read = gps_port->read();
	if (btn_gps_type==1){
		if (last_byte=='@'&&gps_port_read=='@'){ // start
			gps_start=1;
			clear_command_buffer();
		}else{
			if (gps_start){
				if (last_byte==0x0D&&gps_port_read==0x0A){ // decode
					gps_start=0;
					control_port_buffer_index=control_port_buffer_index-2;
					if (control_port_buffer[control_port_buffer_index] &&0x10){
				//		Serial.println("3D fix");
						gps_data_available = 1;

					}
				}else{
					control_port_buffer[control_port_buffer_index] = gps_port_read;
					control_port_buffer_index++;
				}
			}
		}
		last_byte=gps_port_read;
	}else
		if (gps.encode(gps_port_read)) {
		gps_data_available = 1;
		}
  }
} /* check_serial */

// -------------------------------------------------------------

void clear_command_buffer(){

  control_port_buffer_index = 0;
  control_port_buffer[0] = 0;
}


char *  latlng2loc(double lat,double lon,char *locator){
    //char locator[7];
	
	locator[10]=0;
	
	lon = lon + 180.0;
	lat = lat + 90.0;
	
	lon = lon / 20.0 + 0.0000001;
	lat = lat / 10.0 + 0.0000001;
	locator[0]=65 +lon;
	locator[1]=(65 + lat);
	lon = lon - int(lon);
	lat = lat - int(lat);
	lon = lon * 10.0;
	lat = lat * 10.0;
	locator[2]=48 +lon;
	locator[3]=(48 + lat);
	lon = lon - int(lon);
	lat = lat - int(lat);
	lon = lon * 24;
	lat = lat * 24;
	locator[4]=65 +lon;
	locator[5]=(65 + lat);

	lon = lon - int(lon);
	lat = lat - int(lat);
	lon = lon * 10.0;
	lat = lat * 10.0;
	locator[6]=48 +lon;
	locator[7]=(48 + lat);

	lon = lon - int(lon);
	lat = lat - int(lat);
	lon = lon * 24;
	lat = lat * 24;
	locator[8]=65 +lon;
	locator[9]=(65 + lat);

	return locator;
}

void check_buttons(){

  static byte moon_tracking_button_pushed = 0;
  static unsigned long last_time_moon_tracking_button_pushed = 0;

  if ((digitalRead(moon_tracking_button) == LOW)) {
      moon_tracking_button_pushed = 1;
      last_time_moon_tracking_button_pushed = millis();
 
    } else {
      if ((moon_tracking_button_pushed) && ((millis() - last_time_moon_tracking_button_pushed) >= 250)) {
        if (!btn_moon_sun) {
          btn_moon_sun = 1;
        } else {
          btn_moon_sun = 0;
        }
        moon_tracking_button_pushed = 0;
      }
    }

  static byte locator_button_pushed = 0;
  static unsigned long last_time_locator_button_pushed = 0;
  if ((digitalRead(locator_button) == LOW)) {
      locator_button_pushed = 1;
      last_time_locator_button_pushed = millis();
 
    } else {
      if ((locator_button_pushed) && ((millis() - last_time_locator_button_pushed) >= 250)) {
        if (!btn_locator) {
          btn_locator = 1;
        } else {
          btn_locator = 0;
        }
        locator_button_pushed = 0;
      }
    }

}